﻿using System;
using System.Collections.Generic;
using System.Xml;
using KingTools.CommonsHelper.Model;

namespace KingTools.XmlHelper
{
    public class XmlUtils
    {
        private readonly XmlDocument xmlDoc = new XmlDocument();
        private string xmlFileName;

        public string FilePath
        {
            set { xmlFileName = value; }
        }

        //创建XML操作对象
        public void OpenXML()
        {
            try
            {
                xmlDoc.Load(xmlFileName);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        /// <summary>
        ///     根据节点，获得子节点列表
        /// </summary>
        /// <param name="strNode"></param>
        /// <returns></returns>
        public List<Item> GetXmlNodesByItemChildNodes(string strNode)
        {
            var Items = new List<Item>();
            XmlNodeList xnl = xmlDoc.SelectSingleNode(strNode).ChildNodes;
            foreach (XmlElement element in xnl)
            {
                var Item = new Item();
                Item.name = element.GetElementsByTagName("name")[0].InnerText;
                Item.value = element.GetElementsByTagName("value")[0].InnerText;
                Items.Add(Item);
            }
            return Items;
        }

        public List<ServerItem> GetXmlNodesByServerItemChildNodes(string strNode)
        {
            var Items = new List<ServerItem>();
            XmlNodeList xnl = xmlDoc.SelectSingleNode(strNode).ChildNodes;
            foreach (XmlElement element in xnl)
            {
                var Item = new ServerItem();
                Item.name = element.GetElementsByTagName("name")[0].InnerText;
                Item.IP = element.GetElementsByTagName("IP")[0].InnerText;
                Item.PORT = element.GetElementsByTagName("PORT")[0].InnerText;
                Items.Add(Item);
            }
            return Items;
        }

        /// <summary>
        ///     获取XML文件的根元素
        /// </summary>
        public XmlNode GetXmlRoot()
        {
            return xmlDoc.DocumentElement;
        }

        /// <summary>
        ///     在根节点下添加父节点
        /// </summary>
        public void AddParentNode(string parentNode)
        {
            XmlNode root = GetXmlRoot();
            XmlNode parentXmlNode = xmlDoc.CreateElement(parentNode);

            root.AppendChild(parentXmlNode);
        }

        /// <summary>
        ///     向一个已经存在的父节点中插入一个子节点
        /// </summary>
        public void AddChildNode(string parentNodePath, string childNodePath)
        {
            XmlNode parentXmlNode = xmlDoc.SelectSingleNode(parentNodePath);
            XmlNode childXmlNode = xmlDoc.CreateElement(childNodePath);

            parentXmlNode.AppendChild(childXmlNode);
        }

        /// <summary>
        ///     向一个节点添加属性
        /// </summary>
        public void AddAttribute(string NodePath, string NodeAttribute)
        {
            XmlAttribute nodeAttribute = xmlDoc.CreateAttribute(NodeAttribute);
            XmlNode nodePath = xmlDoc.SelectSingleNode(NodePath);
            nodePath.Attributes.Append(nodeAttribute);
        }

        /// <summary>
        ///     删除一个节点的属性
        /// </summary>
        public void DeleteAttribute(string NodePath, string NodeAttribute, string NodeAttributeValue)
        {
            XmlNodeList nodePath = xmlDoc.SelectSingleNode(NodePath).ChildNodes;

            foreach (XmlNode xn in nodePath)
            {
                var xe = (XmlElement) xn;

                if (xe.GetAttribute(NodeAttribute) == NodeAttributeValue)
                {
                    xe.RemoveAttribute(NodeAttribute); //删除属性
                }
            }
        }

        /// <summary>
        ///     删除一个节点
        /// </summary>
        public void DeleteXmlNode(string tempXmlNode)
        {
            //XmlNodeList xmlNodePath=xmlDoc.SelectSingleNode(tempXmlNode).ChildNodes;

            XmlNode xmlNodePath = xmlDoc.SelectSingleNode(tempXmlNode);
            xmlNodePath.ParentNode.RemoveChild(xmlNodePath);
            //foreach(XmlNode xn in xmlNodePath)
            //{
            //XmlElement xe=(XmlElement)xn;
            //xe.RemoveAll();
            //xe.RemoveChild(xn);

            //xn.RemoveAll();

            //if(xe.HasChildNodes)
            //{

            //foreach(XmlNode xn in xe)
            //{

            //xn.RemoveAll();//删除所有子节点和属性
            //}
            //}

            //}
        }

        #region 保存XML文件

        /// <summary>
        ///     功能:
        ///     保存XML文件
        /// </summary>
        public void SaveXmlDocument()
        {
            try
            {
                //保存设置的结果
                xmlDoc.Save(xmlFileName);
            }
            catch (XmlException xmle)
            {
                throw xmle;
            }
        }

        #endregion

        #region 保存XML文件

        /// <summary>
        ///     功能:
        ///     保存XML文件
        /// </summary>
        public void SaveXmlDocument(string tempXMLFilePath)
        {
            try
            {
                //保存设置的结果
                xmlDoc.Save(tempXMLFilePath);
            }
            catch (XmlException xmle)
            {
                throw xmle;
            }
        }

        #endregion

        #region 读取指定节点的值

        /// <summary>
        ///     功能:
        ///     读取指定节点的值
        ///     参数:
        ///     参数:节点名称
        /// </summary>
        /// <param name="strNode"></param>
        /// <returns></returns>
        public string GetXmlNodeValue(string strNode)
        {
            string strReturn = String.Empty;
            try
            {
                //根据路径获取节点
                XmlNode xmlNode = xmlDoc.SelectSingleNode(strNode);
                strReturn = xmlNode.InnerText;
            }
            catch (XmlException xmle)
            {
                Console.WriteLine(xmle.Message);
            }
            return strReturn;
        }

        #endregion

        #region 设置节点值

        /// <summary>
        ///     功能:
        ///     设置节点值
        ///     参数:
        ///     参数一:节点的名称
        ///     参数二:节点值
        /// </summary>
        /// <param name="strNode"></param>
        /// <param name="newValue"></param>
        public void SetXmlNodeValue(string xmlNodePath, string xmlNodeValue)
        {
            try
            {
                //根据指定路径获取节点
                XmlNode xmlNode = xmlDoc.SelectSingleNode(xmlNodePath);
                //设置节点值
                xmlNode.InnerText = xmlNodeValue;
            }
            catch (XmlException xmle)
            {
                throw xmle;
            }
        }

        #endregion

        #region 设置节点的属性值

        /// <summary>
        ///     功能:
        ///     设置节点的属性值
        ///     参数:
        ///     参数一:节点名称
        ///     参数二:属性名称
        ///     参数三:属性值
        /// </summary>
        /// <param name="xmlNodePath"></param>
        /// <param name="xmlNodeAttribute"></param>
        /// <param name="xmlNodeAttributeValue"></param>
        public void SetXmlNodeValue(string xmlNodePath, string xmlNodeAttribute, string xmlNodeAttributeValue)
        {
            try
            {
                //根据指定路径获取节点
                XmlNode xmlNode = xmlDoc.SelectSingleNode(xmlNodePath);

                //获取节点的属性，并循环取出需要的属性值
                XmlAttributeCollection xmlAttr = xmlNode.Attributes;
                for (int i = 0; i < xmlAttr.Count; i++)
                {
                    if (xmlAttr.Item(i).Name == xmlNodeAttribute)
                    {
                        xmlAttr.Item(i).Value = xmlNodeAttributeValue;
                        break;
                    }
                }
            }
            catch (XmlException xmle)
            {
                throw xmle;
            }
        }

        #endregion

        #region 读取指定节点的指定属性值

        /// <summary>
        ///     功能:
        ///     读取指定节点的指定属性值
        ///     参数:
        ///     参数一:节点名称
        ///     参数二:此节点的属性
        /// </summary>
        /// <param name="strNode"></param>
        /// <param name="strAttribute"></param>
        /// <returns></returns>
        public string GetXmlNodeValue(string strNode, string strAttribute)
        {
            string strReturn = "";
            try
            {
                //根据指定路径获取节点
                XmlNode xmlNode = xmlDoc.SelectSingleNode(strNode);
                //获取节点的属性，并循环取出需要的属性值
                XmlAttributeCollection xmlAttr = xmlNode.Attributes;

                for (int i = 0; i < xmlAttr.Count; i++)
                {
                    if (xmlAttr.Item(i).Name == strAttribute)
                        strReturn = xmlAttr.Item(i).Value;
                }
            }
            catch (XmlException xmle)
            {
                throw xmle;
            }
            return strReturn;
        }

        #endregion
    }
}